package com.school.information.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.school.information.core.constant.CommonConstant;
import com.school.information.core.exception.ServiceException;
import com.school.information.core.service.RedisService;
import com.school.information.entity.BasicSchoolEntity;
import com.school.information.enums.result.BasicResultEnum;
import com.school.information.mapper.BasicSchoolMapper;
import com.school.information.qo.BasicSchoolQO;
import com.school.information.service.BasicSchoolService;
import com.school.information.utils.GenrateCodeUtil;
import com.school.information.utils.baidu.BaiDuMapUtil;
import com.school.information.utils.baidu.dto.BaiduMapPointDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * (BasicSchool)表服务实现类
 *
 * @author ycc
 * @since 2023-11-07 14:44:46
 */
@Service
@Slf4j
public class BasicSchoolServiceImpl extends ServiceImpl<BasicSchoolMapper, BasicSchoolEntity> implements BasicSchoolService {

    @Resource
    private RedisService redisService;

    @Override
    public IPage<BasicSchoolEntity> pageList(BasicSchoolQO basicSchoolQO) {
        LambdaQueryWrapper<BasicSchoolEntity> queryWrapper = Wrappers.<BasicSchoolEntity>query().lambda().orderByDesc(BasicSchoolEntity::getUpdateTime);
        if (StringUtils.isNotBlank(basicSchoolQO.getName())) {
            queryWrapper.like(BasicSchoolEntity::getName, basicSchoolQO.getName());
        }
        if (StringUtils.isNotBlank(basicSchoolQO.getCode())) {
            queryWrapper.eq(BasicSchoolEntity::getCode, basicSchoolQO.getCode());
        }
        return this.page(new Page<>(basicSchoolQO.getCurrent(), basicSchoolQO.getSize()), queryWrapper);
    }

    @Override
    public String getMaxCode() {
        // 当 redis中不存在key时 会自动新增一个key  默认值为0
//        redisService.incr(CommonConstant.PREFIX_ROLE_CODE, 1);
        String newCode = "";
        if (!redisService.hasKey(CommonConstant.PREFIX_SCHOOl_CODE)) {
            redisService.incr(CommonConstant.PREFIX_SCHOOl_CODE, 1);
        }
        newCode = GenrateCodeUtil.getNewAutoNum(CommonConstant.PREFIX_SCHOOl_CODE, 3, (int) redisService.get(CommonConstant.PREFIX_SCHOOl_CODE));
        return newCode;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveInfo(BasicSchoolEntity basicSchool) {
        boolean result = false;
        // 验证学校编码、名称是否存在
        BasicSchoolEntity schoolCode = getByCode(basicSchool.getCode());
        if (Objects.nonNull(schoolCode) && StringUtils.isNotBlank(schoolCode.getCode())) {
            log.error("##学校编码{}已存在", schoolCode.getCode());
            throw new ServiceException(BasicResultEnum.SCHOOL_KEY_EXISTED);
        }
        BasicSchoolEntity schoolName = getByName(basicSchool.getName());
        if (Objects.nonNull(schoolName) && StringUtils.isNotBlank(schoolName.getName())) {
            log.error("##学校名称{}已存在", schoolName.getName());
            throw new ServiceException(BasicResultEnum.SCHOOL_NAME_EXISTED);
        }
        try {
            // 获取经纬度信息
            BaiduMapPointDTO mapPointDTO = BaiDuMapUtil.getPoint(basicSchool.getAddress());
            basicSchool.setLat(mapPointDTO.getLat()).setLng(mapPointDTO.getLng());
            result = this.save(basicSchool);
            // 插入成功后，学校编码自增1
            redisService.incr(CommonConstant.PREFIX_SCHOOl_CODE, 1);
        } catch (DuplicateKeyException e) {
            log.error("##唯一索引异常");
            throw new ServiceException(BasicResultEnum.SCHOOL_UK_INDEX_EXCEPTION);
        } catch (Exception e) {
            throw new ServiceException(BasicResultEnum.SCHOOL_ADDRESS_LNG_LAT_FAIL);
        }
        return result;
    }

    @Override
    public BasicSchoolEntity getByCode(String code) {
        return this.getOne(Wrappers.<BasicSchoolEntity>lambdaQuery().eq(BasicSchoolEntity::getCode, code));
    }

    @Override
    public BasicSchoolEntity getByName(String name) {
        return this.getOne(Wrappers.<BasicSchoolEntity>lambdaQuery().eq(BasicSchoolEntity::getName, name));
    }

    @Override
    public boolean updateInfo(BasicSchoolEntity basicSchool) {
        boolean result = false;
        BasicSchoolEntity oldSchool = this.getById(basicSchool.getId());
        // 验证学校编码、名称是否存在
        BasicSchoolEntity schoolCode = getByCode(basicSchool.getCode());
        if (Objects.nonNull(schoolCode) && StringUtils.isNotBlank(schoolCode.getCode())
                && !schoolCode.getCode().equals(oldSchool.getCode())) {
            log.error("##学校编码{}已存在", schoolCode.getCode());
            throw new ServiceException(BasicResultEnum.SCHOOL_KEY_EXISTED);
        }
        BasicSchoolEntity schoolName = getByName(basicSchool.getName());
        if (Objects.nonNull(schoolName) && StringUtils.isNotBlank(schoolName.getName())
                && !schoolName.getName().equals(oldSchool.getName())) {
            log.error("##学校名称{}已存在", schoolName.getName());
            throw new ServiceException(BasicResultEnum.SCHOOL_NAME_EXISTED);
        }
        try {
            // 获取经纬度信息
            BaiduMapPointDTO mapPointDTO = BaiDuMapUtil.getPoint(basicSchool.getAddress());
            oldSchool.setLat(mapPointDTO.getLat()).setLng(mapPointDTO.getLng());
        } catch (Exception e) {
            throw new ServiceException(BasicResultEnum.SCHOOL_ADDRESS_LNG_LAT_FAIL);
        }
        oldSchool.setName(basicSchool.getName()).setAddress(basicSchool.getAddress()).setRemark(basicSchool.getRemark());
        result = this.updateById(oldSchool);
        return result;
    }

    @Override
    public List<BasicSchoolEntity> findList() {
        return this.list();
    }
}
